
Rem
bbdoc: Camera System.
about: Follows the entity with the TCamera component.
Required component: TPosition, TCamera.
endrem
Type TCameraSystem Extends TEntityProcessingSystem
	
	'needed to get game width and height for viewport
	Field _game:TGame

	Field _positionMapper:TComponentMapper
		
	'camera position in the game world
	Field _position:TVector2D
	Field _previousPosition:TVector2D
	
	'position to focus on. (is put in center of screen)
	'default is gameres/2 for static screen games
	'or set it to the reference of an object position vector.
	Field _focusPosition:TVector2D
	
	'direction to focus position.
	Field _focusVector:TVector2D

	'move vector is multiplied by this amount.
	Field _damping:Float
	
	
	
	Method Initialize()
		_positionMapper = TComponentMapper.Create(New TPositionComponent, _world)
		RegisterComponent(New TPositionComponent)
		RegisterComponent(New TCameraComponent)
		
		_position = New TVector2D
		_previousPosition = New TVector2D
		_focusPosition = New TVector2D
		_focusVector = New TVector2D
		_damping = 1.0
		
		'center on screen
		ResetPosition(_game.GetWidth() / 2, _game.GetHeight() / 2)
	End Method
	
	
	'moves the camera towards the followed entity.
	Method ProcessEntity(e:TEntity)
		Local p:TPositionComponent = TPositionComponent(_positionMapper.Get(e))
		Local v:TVector2D = p.Get()
		
		'update the camera system settings
		'work out vector from camera position to focus position
		_focusVector.Copy(v)
		_focusVector.SubstractV(_position)
		
		'multiply that vector by damping value
		_focusVector.Multiply(_damping)
		
		'move camera. no tweening, etc.
		_previousPosition.Copy(_position)
		_position.AddV(_focusVector)
		
		'set the new camera origin
		'this is added to every draw operation, after rotation and scale.
		
		SetOrigin(_game.GetWidth() / 2 - _position.GetX(),  ..
					_game.GetHeight() / 2 - _position.GetY())
	End Method
	
	
	Method ResetPosition(worldx:Int, worldy:Float)
		_position.Set(worldx, worldy)
		_previousPosition.Set(worldx, worldy)
		_focusVector.Set(0, 0)
	End Method
	
	
	'returns the current world view of the camera.
	Method GetViewport:TRect()
		Return TRect.Create(_position.GetX(), _position.GetY(),  ..
				_game.GetWidth(), _game.GetHeight(), True)
	End Method
	
	
	Method SetDamping(v:Float)
		If v > 1.0 Then v = 1.0
		_damping = v
	End Method
	
	
	Method SetGame(g:TGame)
		_game = g
	End Method
	
	
	Method PosToString:String()
		Return "Camera Pos: " + Int(_position.GetX()) + "," + Int(_position.GetY())
	End Method
	
	
	Method ViewToString:String()
		Local view:TRect = Self.GetViewport()
		Return "Viewport: " + Int(view.GetX()) + "," + Int(view.GetY()) + " to " + ..
			(Int(view.GetX() + view.GetWidth())) + "," + (Int(view.GetY() + view.GetHeight()))
	End Method
	
End Type
